package de.rj.urwalking.data.survey;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;

import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;

import de.rj.urwalking.data.survey.Question.OnAnswerChangedListener;

/**
 * A Survey consists of and manages a set of Questions.
 * 
 * @author rjj
 * 
 */

public class Survey implements Serializable {

	private static final long serialVersionUID = 1L;
	@ElementList
	protected ArrayList<Question> questions;
	protected HashMap<Integer, ArrayList<Question>> questionScreens = new HashMap<Integer, ArrayList<Question>>();
	protected ArrayList<Integer> screenHistory = new ArrayList<Integer>();
	@Element(name="timestampdate")
	protected long timestamp;

	public Survey(ArrayList<Question> questions) {

		this.questions = questions;
		screenHistory.add(1);
		populateScreenHashMap();
	}

	public long getTimestamp() {
		return timestamp;
	}

	public void setTimestamp(long timestamp) {
		this.timestamp = timestamp;
	}

	/**
	 * Returns the last item of the screen history.
	 * 
	 */
	public int getCurrentScreenNr() {
		return screenHistory.get(screenHistory.size() - 1);
	}

	/**
	 * Puts an Integer that is one greater than the current screen number onto the screen history stack.
	 */
	public void nextScreen() {
		screenHistory.add(getCurrentScreenNr() + 1);
	}

	/**
	 * Asks all of the currently shown questions if they have been answered. Used to determine if the user may proceed
	 * to the next screen.
	 */
	public boolean areCurrentQuestionsAnswered() {

		ArrayList<Question> questionScreen = questionScreens.get(getCurrentScreenNr());

		for (Question q : questionScreen) {
			if (q.canBeAnswered() && !q.hasBeenAnswered()) {
				return false;
			}
		}
		return true;
	}

	public ArrayList<Question> getCurrentQuestions() {
		return questionScreens.get(getCurrentScreenNr());
	}

	
	public int getScreenCount() {
		return questionScreens.keySet().size();
	}

	/**
	 * Arranges the Questions by screen to allow easier access.
	 */
	protected void populateScreenHashMap() {

		for (Question q : questions) {
			int screenId = q.getScreen();

			if (questionScreens.get(screenId) == null) {
				questionScreens.put(screenId, new ArrayList<Question>());
			}
			questionScreens.get(screenId).add(q);
		}
	}
	
	public void setCallbackForQuestions(OnAnswerChangedListener listener) {
		for (Question q : questions) {
			q.setCallback(listener);
		}
	}

	/**
	 * Checks how many of the questions on the current screen have already been answered.
	 */
	public int getNumCurrentlyAnsweredQuestions() {
	
		int numAnswered = 0;
	
		for (Question q : getCurrentQuestions()) {
			if (q.hasBeenAnswered()) {
				numAnswered++;
			}
		}
		return numAnswered;
	}

	/**
	 * Checks how many of the questions on the current screen have to be answered.
	 */
	public int getNumCurrentlyAnswerableQuestions() {
	
		int numAnswerable = 0;
	
		for (Question q : getCurrentQuestions()) {
			if (q.canBeAnswered()) {
				numAnswerable++;
			}
		}
		return numAnswerable;
	
	}

}
